using System.Collections.Generic;
using System.Linq;
using FireStarterModeller.BO;
using FireStarterModeller.Logic;
using FireStarterModeller.Logic.Wizards;
using FireStarterModeller.Test.BO;
using FireStarterModeller.UI;
using Habanero.Base.Exceptions;
using Habanero.BO;
using Habanero.Faces.Base;
using Habanero.Testability;
using NUnit.Framework;

namespace FireStarterModeller.Test.UI
{
    [TestFixture]
    public class TestCreateViewWizardController
    {
        //protected static readonly DatabaseConfig _databaseConfig = new DatabaseConfig
        //    (DatabaseConfig.SqlServer, "localhost", "lgta_LGMIS_Definition_test", "sa", "sa", "1000");
        [SetUp]
        public void SetupTest()
        {
            //Runs every time that any testmethod is executed
            UITestUtils.SetupTest();
            BORegistry.DataAccessor = new DataAccessorInMemory();
        }

        [TestFixtureSetUp]
        public void TestFixtureSetup()
        {
            //Code that is executed before any test is run in this class. If multiple tests
            // are executed then it will still only be called once
            UITestUtils.SetupFixture();
        }

        [TearDown]
        public void TearDownTest()
        {
            //runs every time any testmethod is complete
        }

        [Test]
        public void Test_ConstructCreateGridController()
        {
            //---------------Set up test pack-------------------

            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            CreateViewWizardController wizardController = new CreateViewWizardController();
            //---------------Test Result -----------------------
            SelectPropertiesWizardStep propertiesWizardStep1 = (SelectPropertiesWizardStep)wizardController.GetFirstStep();
            SelectPropertiesFilterWizardStep propertiesWizardStep2 = (SelectPropertiesFilterWizardStep)wizardController.GetNextStep();
            SelectPropertiesWizardStep propertiesWizardStep3 = (SelectPropertiesWizardStep)wizardController.GetNextStep();
            Assert.IsInstanceOf(typeof (IWizardController), wizardController);
            Assert.AreEqual(3, wizardController.StepCount);
            Assert.IsInstanceOf(typeof(SelectPropertiesWizardStep), propertiesWizardStep1);
            Assert.IsInstanceOf(typeof (SelectPropertiesFilterWizardStep), propertiesWizardStep2);
            Assert.IsInstanceOf(typeof(SelectPropertiesWizardStep), propertiesWizardStep3);
            string expectedTextWizardStep1 = "1. Please select an entity and the properties to show in the grid.";
            string expectedTextWizardStep2 = "2. Please select filters to show for the grid.";
            string expectedTextWizardStep3 = "3. Please select properties to show on the form.";
            Assert.AreEqual(expectedTextWizardStep1, propertiesWizardStep1.Label.Text);
            Assert.AreEqual(expectedTextWizardStep2, propertiesWizardStep2.Label.Text);
            Assert.AreEqual(expectedTextWizardStep3, propertiesWizardStep3.Label.Text);
            Assert.IsFalse(propertiesWizardStep3.ClassSelectorControl.Visible);
        }

        //TODO: if no filter props are selected should not create filter def
        //TODO: If no grid props are selected should not create grid def.

        [Test]
        public void Test_SetClass_ShouldSetClassToWizardStep()
        {
            //---------------Set up test pack-------------------
            CreateViewWizardController wizardController = new CreateViewWizardController();
            SelectPropertiesWizardStep propertiesWizardStep1 = (SelectPropertiesWizardStep) wizardController.GetFirstStep();
            SelectPropertiesFilterWizardStep propertiesWizardStep2 = (SelectPropertiesFilterWizardStep) wizardController.GetNextStep();
            SelectPropertiesWizardStep propertiesWizardStep3 = (SelectPropertiesWizardStep) wizardController.GetNextStep();
            DMSolution solution = TestUtilsDMSolution.CreateSavedDMSolutionWithTwoClasses();
            DMClass dmClass = solution.AllClasses[1];
            dmClass.Properties.CreateBusinessObject().PropertyName = TestUtilsShared.GetRandomString();
            dmClass.Properties.CreateBusinessObject().PropertyName = TestUtilsShared.GetRandomString();
            //---------------Assert Precondition----------------
            Assert.IsNull(wizardController.Class);
            Assert.IsNull(propertiesWizardStep1.SelectedClass);
            Assert.AreNotSame(propertiesWizardStep1, propertiesWizardStep2);
            Assert.AreNotSame(propertiesWizardStep2, propertiesWizardStep3);
            //---------------Execute Test ----------------------
            wizardController.Class = dmClass;
            //---------------Test Result -----------------------
            Assert.IsNotNull(wizardController.Class);
            Assert.AreSame(dmClass, propertiesWizardStep1.SelectedClass);
            Assert.AreSame(dmClass, propertiesWizardStep2.SelectedClass);
            Assert.AreSame(dmClass, propertiesWizardStep3.SelectedClass);
        }

        [Test]
        public void Test_SetSolution_ShouldSetSolutionToWizardStep()
        {
            CreateViewWizardController wizardController = new CreateViewWizardController();
            SelectPropertiesWizardStep propertiesWizardStep1 = (SelectPropertiesWizardStep) wizardController.GetFirstStep();
            SelectPropertiesFilterWizardStep propertiesWizardStep2 = (SelectPropertiesFilterWizardStep) wizardController.GetNextStep();
            DMSolution solution = TestUtilsDMSolution.CreateSavedDMSolutionWithTwoClasses();

            DMClass dmClass = solution.AllClasses[1];
            dmClass.Properties.CreateBusinessObject().PropertyName = TestUtilsShared.GetRandomString();
            dmClass.Properties.CreateBusinessObject().PropertyName = TestUtilsShared.GetRandomString();
            //---------------Assert Precondition----------------
            Assert.IsNull(wizardController.Solution);
            Assert.IsNull(propertiesWizardStep1.Solution);
            Assert.AreNotSame(propertiesWizardStep1, propertiesWizardStep2);
            //---------------Execute Test ----------------------
            wizardController.Solution = solution;
            //---------------Test Result -----------------------
            Assert.IsNotNull(wizardController.Solution);
            Assert.IsNotNull(propertiesWizardStep1.Solution);
            Assert.IsNull(propertiesWizardStep2.Solution);
            Assert.AreSame(solution, wizardController.Solution);
            Assert.AreSame(solution, propertiesWizardStep1.Solution);
        }

        [Test]
        public void Test_SelectClassForGridCreator_ShouldSetClassForGridFilterCreator()
        {
            //---------------Set up test pack-------------------
            CreateViewWizardController wizardController = new CreateViewWizardController();
            SelectPropertiesWizardStep propertiesWizardStep1 = (SelectPropertiesWizardStep) wizardController.GetFirstStep();
            SelectPropertiesFilterWizardStep propertiesWizardStep2 = (SelectPropertiesFilterWizardStep) wizardController.GetNextStep();
            SelectPropertiesWizardStep propertiesWizardStep3 = (SelectPropertiesWizardStep)wizardController.GetNextStep();
            DMSolution solution = TestUtilsDMSolution.CreateSavedDMSolutionWithTwoClasses();
            wizardController.Solution = solution;
            //---------------Assert Precondition----------------
            Assert.IsNull(propertiesWizardStep2.Solution);
            Assert.IsNull(propertiesWizardStep2.SelectedClass);
            Assert.AreSame(solution, wizardController.Solution);
            Assert.AreSame(solution, propertiesWizardStep1.Solution);
            //---------------Execute Test ----------------------
            DMClass selectedDMClass = solution.AllClasses[0];
            propertiesWizardStep1.ClassSelectorControl.SelectedBusinessObject = selectedDMClass;
            //---------------Test Result -----------------------
            Assert.IsNotNull(propertiesWizardStep1.SelectedClass);
            Assert.AreSame(selectedDMClass, propertiesWizardStep1.SelectedClass);
            Assert.IsNotNull(propertiesWizardStep2.Solution);
            Assert.AreSame(selectedDMClass, propertiesWizardStep2.SelectedClass);
            Assert.AreSame(selectedDMClass, propertiesWizardStep3.SelectedClass);
        }

        [Test]
        public void TestAcceptance_Finish_ShouldCreateUIGridWithSelectedProperties()
        {
            //---------------Set up test pack-------------------
            CreateViewWizardController wizardController = new CreateViewWizardController();
            SelectPropertiesWizardStep propertyColumnsWizardStep =
                (SelectPropertiesWizardStep) wizardController.GetFirstStep();

            DMSolution solution = TestUtilsDMSolution.CreateSavedDMSolutionWithTwoClasses();
            DMClass dmClass = solution.AllClasses[1];
            TestUtilsDMProperty.CreateUnsavedValidDMProperty(dmClass);
            DMProperty selectedProp = TestUtilsDMProperty.CreateUnsavedValidDMProperty(dmClass, false);
            wizardController.Class = dmClass;
            IMultiSelector<string> propertiesSelectorControl = propertyColumnsWizardStep.PropertiesSelectorControl;
            propertiesSelectorControl.Model.Select(selectedProp.PropertyName);
            selectedProp.ObjectIdentity = null;
            wizardController.GetNextStep();
            wizardController.GetNextStep();
            //---------------Assert Precondition----------------
            Assert.IsNotNull(wizardController.Class);
            Assert.IsNull(wizardController.UIGrid);
            IList<string> availableOptions = propertiesSelectorControl.Model.AvailableOptions;
            Assert.AreEqual(1, availableOptions.Count);
            IList<string> selectedOptions = propertiesSelectorControl.SelectedOptions;
            Assert.AreEqual(1, selectedOptions.Count);
            Assert.IsFalse(selectedProp.IsPartOfObjectIdentity);
            Assert.IsFalse(selectedProp.KeepValuePrivate.GetValueOrDefault());
            //---------------Execute Test ----------------------
            wizardController.Finish();
            //---------------Test Result -----------------------
            UIGridInfo gridInfo = wizardController.UIGrid;
            Assert.IsNotNull(gridInfo);
            BusinessObjectCollection<UIGridColumnInfo> gridColumnInfos = gridInfo.UIColumns;
            Assert.AreEqual(1, gridColumnInfos.Count);
            UIGridColumnInfo gridColumnInfo = gridColumnInfos[0];
            Assert.AreEqual(selectedProp.PropertyName, gridColumnInfo.PropertyName);
        }

        [Test]
        public void TestAcceptance_Finish_ShouldCreateUIGridWithSelectedProperties_AndShouldCreateUIGridFilterWithSelectedProperties()
        {
            //---------------Set up test pack-------------------
            CreateViewWizardController wizardController = new CreateViewWizardController();
            SelectPropertiesWizardStep propertyColumnsWizardStep = (SelectPropertiesWizardStep) wizardController.GetFirstStep();
            
            DMSolution solution = TestUtilsDMSolution.CreateSavedDMSolutionWithTwoClasses();
            DMClass dmClass = solution.AllClasses[1];
            DMProperty property = TestUtilsDMProperty.CreateUnsavedValidDMProperty(dmClass);
            property.PropertyName = TestUtilsShared.GetRandomString();
            DMProperty selectedProp = TestUtilsDMProperty.CreateUnsavedValidDMProperty(dmClass, false);
            selectedProp.PropertyName = TestUtilsShared.GetRandomString();
            //wizardController.Class = dmClass;
            wizardController.Solution = solution;
            IMultiSelector<string> propertiesSelectorControl = propertyColumnsWizardStep.PropertiesSelectorControl;
            propertyColumnsWizardStep.ClassSelectorControl.SelectedBusinessObject = dmClass;
            propertiesSelectorControl.Model.Select(selectedProp.PropertyName);
            selectedProp.ObjectIdentity = null;
            SelectPropertiesFilterWizardStep propertyFilterWizardStep = (SelectPropertiesFilterWizardStep) wizardController.GetNextStep();
            wizardController.GetNextStep();
            //---------------Assert Precondition----------------
            Assert.IsNotNull(wizardController.Class);
            Assert.IsNull(wizardController.UIGrid);
            IList<string> availableOptions = propertiesSelectorControl.Model.AvailableOptions;
            Assert.AreEqual(1, availableOptions.Count);
            IList<string> selectedOptions = propertiesSelectorControl.SelectedOptions;
            Assert.AreEqual(1, selectedOptions.Count);
            Assert.IsFalse(selectedProp.IsPartOfObjectIdentity);
            Assert.IsFalse(selectedProp.KeepValuePrivate.GetValueOrDefault());
            Assert.IsNull(wizardController.GridFilter);
            Assert.IsFalse(propertyFilterWizardStep.ClassSelectorControl.Visible);
            Assert.AreSame(propertyColumnsWizardStep.SelectedClass, propertyFilterWizardStep.SelectedClass);
            //---------------Execute Test ----------------------
            propertyFilterWizardStep.PropertiesSelectorControl.Model.Select(selectedProp.PropertyName);
            wizardController.Finish();
            //---------------Test Result -----------------------
            UIGridInfo gridInfo = wizardController.UIGrid;
            Assert.IsNotNull(gridInfo);
            BusinessObjectCollection<UIGridColumnInfo> gridColumnInfos = gridInfo.UIColumns;
            Assert.AreEqual(1, gridColumnInfos.Count);
            UIGridColumnInfo gridColumnInfo = gridColumnInfos[0];
            Assert.AreEqual(selectedProp.PropertyName, gridColumnInfo.PropertyName);

            UIGridFilter gridFilter = wizardController.GridFilter;
            Assert.IsNotNull(gridFilter);
            BusinessObjectCollection<UIGridFilterProp> gridFilterProps = gridFilter.UIGridFilterProps;
            Assert.AreEqual(1, gridFilterProps.Count);
            UIGridFilterProp gridFilterProp = gridFilterProps[0];
            Assert.AreEqual(selectedProp.PropertyName, gridFilterProp.PropertyName);
            Assert.AreSame(gridInfo, gridFilter.UIGridInfo);
            Assert.IsNotNull(gridInfo.UIView);
            Assert.AreEqual(1, dmClass.UIViews.Count);
            UIView uiView = dmClass.UIViews[0];
            Assert.AreSame(uiView, gridInfo.UIView);
            Assert.IsNotNull(uiView.UIFormInfo);
//            Assert.AreEqual(dmClass.Properties.Count, uiView.UIFormInfo.UIFields.Count);
            //Assert.AreEqual("default",uiView.ViewName);
        }

        [Test]
        public void TestAcceptance_Finish_ShouldNameViewUniquely()
        {
            //---------------Set up test pack-------------------
            CreateViewWizardController wizardController = new CreateViewWizardController();
            SelectPropertiesWizardStep propertyColumnsWizardStep =
                (SelectPropertiesWizardStep)wizardController.GetFirstStep();


            DMSolution solution = TestUtilsDMSolution.CreateSavedDMSolutionWithTwoClasses();
            DMClass dmClass = solution.AllClasses[1];
            UIView uiView1 = dmClass.UIViews.CreateBusinessObject();
            DMProperty property = TestUtilsDMProperty.CreateUnsavedValidDMProperty(dmClass);
            property.PropertyName = TestUtilsShared.GetRandomString();
            DMProperty selectedProp = TestUtilsDMProperty.CreateUnsavedValidDMProperty(dmClass, false);
            selectedProp.PropertyName = TestUtilsShared.GetRandomString();
            //wizardController.Class = dmClass;
            wizardController.Solution = solution;
            IMultiSelector<string> propertiesSelectorControl = propertyColumnsWizardStep.PropertiesSelectorControl;
            propertyColumnsWizardStep.ClassSelectorControl.SelectedBusinessObject = dmClass;
            propertiesSelectorControl.Model.Select(selectedProp.PropertyName);
            selectedProp.ObjectIdentity = null;
            SelectPropertiesFilterWizardStep propertyFilterWizardStep = (SelectPropertiesFilterWizardStep)wizardController.GetNextStep();
            wizardController.GetNextStep();
            //---------------Assert Precondition----------------
            Assert.AreEqual(1, dmClass.UIViews.Count);
            Assert.AreEqual("default", uiView1.ViewName);
            Assert.IsNotNull(wizardController.Class);
            Assert.IsNull(wizardController.UIGrid);
            IList<string> availableOptions = propertiesSelectorControl.Model.AvailableOptions;
            Assert.AreEqual(1, availableOptions.Count);
            IList<string> selectedOptions = propertiesSelectorControl.SelectedOptions;
            Assert.AreEqual(1, selectedOptions.Count);
            Assert.IsFalse(selectedProp.IsPartOfObjectIdentity);
            Assert.IsFalse(selectedProp.KeepValuePrivate.GetValueOrDefault());
            Assert.IsNull(wizardController.GridFilter);
            Assert.IsFalse(propertyFilterWizardStep.ClassSelectorControl.Visible);
            Assert.AreSame(propertyColumnsWizardStep.SelectedClass, propertyFilterWizardStep.SelectedClass);
            //---------------Execute Test ----------------------
            propertyFilterWizardStep.PropertiesSelectorControl.Model.Select(selectedProp.PropertyName);
            wizardController.Finish();
            //---------------Test Result -----------------------
            UIGridInfo gridInfo = wizardController.UIGrid;
            Assert.IsNotNull(gridInfo);
            BusinessObjectCollection<UIGridColumnInfo> gridColumnInfos = gridInfo.UIColumns;
            Assert.AreEqual(1, gridColumnInfos.Count);
            UIGridColumnInfo gridColumnInfo = gridColumnInfos[0];
            Assert.AreEqual(selectedProp.PropertyName, gridColumnInfo.PropertyName);

            UIGridFilter gridFilter = wizardController.GridFilter;
            Assert.IsNotNull(gridFilter);
            BusinessObjectCollection<UIGridFilterProp> gridFilterProps = gridFilter.UIGridFilterProps;
            Assert.AreEqual(1, gridFilterProps.Count);
            UIGridFilterProp gridFilterProp = gridFilterProps[0];
            Assert.AreEqual(selectedProp.PropertyName, gridFilterProp.PropertyName);
            Assert.AreSame(gridInfo, gridFilter.UIGridInfo);
            Assert.IsNotNull(gridInfo.UIView);
            Assert.AreEqual(2, dmClass.UIViews.Count);
            UIView uiView = dmClass.UIViews[1];
            Assert.AreSame(uiView, gridInfo.UIView);
            Assert.AreEqual("default1", uiView.ViewName);
        }

        [Test]
        public void TestAcceptance_Finish_ShouldCreateUIGridAndUIGridFilterWithSelectedProperties()
        {
            //---------------Set up test pack-------------------
            CreateViewWizardController wizardController = new CreateViewWizardController();
            IWizardControl wzrdControl = GlobalUIRegistry.ControlFactory.CreateWizardControl(wizardController);
            wzrdControl.Start();
            SelectPropertiesWizardStep gridPropSelector = (SelectPropertiesWizardStep) wizardController.GetFirstStep();

            DMSolution solution = TestUtilsDMSolution.CreateSavedDMSolutionWithTwoClasses();
            DMClass dmClass = solution.AllClasses[1];
            TestUtilsDMProperty.CreateUnsavedValidDMProperty(dmClass);
            DMProperty selectedProp = TestUtilsDMProperty.CreateUnsavedValidDMProperty(dmClass);

            wizardController.Class = dmClass;
            IMultiSelector<string> propertiesMultiSelectorControl = gridPropSelector.PropertiesSelectorControl;
            propertiesMultiSelectorControl.Model.Select(selectedProp.PropertyName);
            selectedProp.ObjectIdentity = null;
            selectedProp.KeepValuePrivate = false;
            //---------------Assert Precondition----------------
            Assert.AreSame(dmClass, wizardController.Class);
            Assert.AreEqual(0, dmClass.UIViews.Count);
            Assert.IsNull(wizardController.GridFilter);
            IList<string> availableOptions = propertiesMultiSelectorControl.Model.AvailableOptions;
            Assert.AreEqual(1, availableOptions.Count);
            IList<string> selectedOptions = propertiesMultiSelectorControl.SelectedOptions;
            Assert.AreEqual(1, selectedOptions.Count);
            Assert.IsFalse(selectedProp.IsPartOfObjectIdentity);
            Assert.IsFalse(selectedProp.KeepValuePrivate.Value);
            SelectPropertiesFilterWizardStep gridFilterPropSelector = wizardController.SelectFilterPropertiesWizardStep;
            Assert.AreEqual(dmClass.Properties.Count, gridFilterPropSelector.PropertiesSelectorControl.Model.AvailableOptions.Count,
                 "Should have all the class properties available");
            Assert.IsTrue(wizardController.IsFirstStep());
            //---------------Execute First Step ----------------------
            wzrdControl.NextButton.PerformClick();
            //---------------Assert Results First Step ---------------
            Assert.IsFalse(wizardController.IsFirstStep());
            //Should Set the Available Options in the Grid Filter to the columns selected in the Grid.
            Assert.AreEqual(1, gridFilterPropSelector.PropertiesSelectorControl.Model.AvailableOptions.Count);

            //--------------Select the Property ----------------------
            IMultiSelector<string> filterPropertiesMultiSelectorControl = gridFilterPropSelector.PropertiesSelectorControl;
            filterPropertiesMultiSelectorControl.Model.Select(selectedProp.PropertyName);

            //--------------Assert Preconditions to Finishd-------------
            IList<string> selectedFilterProps = propertiesMultiSelectorControl.SelectedOptions;
            Assert.AreEqual(1, selectedFilterProps.Count);
            Assert.IsNull(wizardController.UIGrid);
            Assert.IsNull(wizardController.GridFilter);

            //--- Execute Second and Third Step (Finish Wizard) ----------------
            wzrdControl.NextButton.PerformClick();
            wzrdControl.FinishButton.PerformClick();
            //----Assert Results Second Step--------------------------
            //Should Create Grid with selected property
            UIGridInfo grid = wizardController.UIGrid;
            Assert.IsNotNull(grid);
            Assert.IsNotNull(grid.UIGridFilter);
            Assert.AreEqual(1, grid.UIColumns.Count);
            //Should Create Grid Filter with Selected Properties.
            Assert.IsNotNull(wizardController.GridFilter);
            UIGridFilter gridFilter = wizardController.GridFilter;
            Assert.AreSame(grid.UIGridFilter, gridFilter);
            Assert.AreEqual(1, gridFilter.UIGridFilterProps.Count);

            //-----------------Verify That A UIView is created for the Class with
            //  The appropriate Grid and Form Infos
            Assert.AreEqual(1, dmClass.UIViews.Count);
            UIView uiView = dmClass.UIViews[0];
            Assert.IsNotNull(uiView.UIGridInfo);
            Assert.AreSame(grid, uiView.UIGridInfo);
            Assert.IsNotNull(uiView.UIFormInfo);
            //Assert.AreEqual(2, uiView.UIFormInfo.UIFields.Count);
            Assert.IsFalse(uiView.Status.IsNew);
        }


        [Test]
        public void TestAcceptance_Finish_ShouldCreateUIGridWithSelectedProperties_NoFilterDefIfNoSelectedProperties()
        {
            //---------------Set up test pack-------------------
            CreateViewWizardController wizardController = new CreateViewWizardController();
            IWizardControl wzrdControl = GlobalUIRegistry.ControlFactory.CreateWizardControl(wizardController);
            wzrdControl.Start();
            SelectPropertiesWizardStep gridPropSelector = (SelectPropertiesWizardStep) wizardController.GetFirstStep();

            DMSolution solution = TestUtilsDMSolution.CreateSavedDMSolutionWithTwoClasses();
            DMClass dmClass = solution.AllClasses[1];
            TestUtilsDMProperty.CreateUnsavedValidDMProperty(dmClass);
            DMProperty selectedProp = TestUtilsDMProperty.CreateUnsavedValidDMProperty(dmClass);

            wizardController.Class = dmClass;
            IMultiSelector<string> propertiesMultiSelectorControl = gridPropSelector.PropertiesSelectorControl;
            propertiesMultiSelectorControl.Model.Select(selectedProp.PropertyName);
            selectedProp.ObjectIdentity = null;
            selectedProp.KeepValuePrivate = false;
            //---------------Assert Precondition----------------
            Assert.AreSame(dmClass, wizardController.Class);
            Assert.AreEqual(0, dmClass.UIViews.Count);
            Assert.IsNull(wizardController.GridFilter);
            IList<string> availableOptions = propertiesMultiSelectorControl.Model.AvailableOptions;
            Assert.AreEqual(1, availableOptions.Count);
            IList<string> selectedOptions = propertiesMultiSelectorControl.SelectedOptions;
            Assert.AreEqual(1, selectedOptions.Count);
            Assert.IsFalse(selectedProp.IsPartOfObjectIdentity);
            Assert.IsFalse(selectedProp.KeepValuePrivate.Value);
            SelectPropertiesFilterWizardStep gridFilterPropSelector = wizardController.SelectFilterPropertiesWizardStep;
            Assert.AreEqual
                (dmClass.Properties.Count, gridFilterPropSelector.PropertiesSelectorControl.Model.AvailableOptions.Count,
                 "Should have all the Classes Properties available");
            Assert.IsTrue(wizardController.IsFirstStep());
            //---------------Execute First Step ----------------------
            wzrdControl.NextButton.PerformClick();
            //---------------Assert Results First Step ---------------
            Assert.IsFalse(wizardController.IsFirstStep());
            //Should Set the Available Options in the Grid Filter to the columns
            // selected in the Grid.
            Assert.AreEqual(1, gridFilterPropSelector.PropertiesSelectorControl.Model.AvailableOptions.Count);

            //--------------Select the Property ----------------------
            IMultiSelector<string> filterPropertiesMultiSelectorControl =
                gridFilterPropSelector.PropertiesSelectorControl;
            filterPropertiesMultiSelectorControl.SelectedOptionsListBox.ClearSelected();
            //--------------Assert Preconditions to Finish-------------
            IList<string> selectedFilterProps = filterPropertiesMultiSelectorControl.SelectedOptions;
            Assert.AreEqual(0, selectedFilterProps.Count);
            Assert.IsNull(wizardController.UIGrid);
            Assert.IsNull(wizardController.GridFilter);

            //--- Execute Second and Third Step (Finish Wizard) ----------------
            wzrdControl.NextButton.PerformClick();
            wzrdControl.FinishButton.PerformClick();
            //----Assert Results Second Step--------------------------
            //Should Create Grid with selected property
            UIGridInfo grid = wizardController.UIGrid;
            Assert.IsNotNull(grid);
            Assert.AreEqual(1, grid.UIColumns.Count);
            //Should Not Create Grid Filter if no Selected Properties.
            Assert.IsNull(wizardController.GridFilter);
            Assert.IsNull(grid.UIGridFilter);

            //-----------------Verify That A UIView is created for the Class with
            //  The appropriate Grid and Form Infos
            Assert.AreEqual(1, dmClass.UIViews.Count);
            UIView uiView = dmClass.UIViews[0];
            Assert.IsNotNull(uiView.UIGridInfo);
            Assert.AreSame(grid, uiView.UIGridInfo);
            Assert.IsNotNull(uiView.UIFormInfo);
//            Assert.AreEqual(2, uiView.UIFormInfo.UIFields.Count);
        }


        [Test]
        public void Test_CannotMoveToNextStep_IfNoSelectedColumnProperties()
        {
            //--------------- Set up test pack ------------------
            CreateViewWizardController wizardController = new CreateViewWizardController();
            SelectPropertiesWizardStep columnPropertiesWizardStep =
                (SelectPropertiesWizardStep) wizardController.GetFirstStep();
            DMSolution solution = TestUtilsDMSolution.CreateSavedDMSolutionWithTwoClasses();
            DMClass dmClass = solution.AllClasses[1];
            dmClass.Properties.CreateBusinessObject().PropertyName = TestUtilsShared.GetRandomString();
            dmClass.Properties.CreateBusinessObject().PropertyName = TestUtilsShared.GetRandomString();
            wizardController.Solution = solution;
            wizardController.Class = dmClass;
            //--------------- Test Preconditions ----------------
            Assert.IsNotNull(wizardController.Class);
            Assert.IsNotNull(columnPropertiesWizardStep.SelectedClass);
            Assert.AreEqual(0, columnPropertiesWizardStep.PropertiesSelectorControl.Model.SelectedOptions.Count);
            //--------------- Execute Test ----------------------
            string message;
            bool canMoveOn = wizardController.CanMoveOn(out message);
            //--------------- Test Result -----------------------
            Assert.IsFalse(canMoveOn);
            StringAssert.Contains("You must select properties to show in the grid before you can move on", message);
        }

        //[Test]
        //public void Test_CannotMoveToNextStep_IfSelectedClassHasUIViews()
        //{
        //    //--------------- Set up test pack ------------------
        //    CreateViewWizardController wizardController = new CreateViewWizardController();
        //    SelectPropertiesWizardStep columnPropertiesWizardStep =
        //        (SelectPropertiesWizardStep) wizardController.GetFirstStep();
        //    DMSolution solution = TestUtilsDMSolution.CreateSavedDMSolutionWithTwoClasses();
        //    DMClass dmClass = solution.AllClasses[1];
        //    DMProperty dmProperty = dmClass.Properties.CreateBusinessObject();
        //    dmProperty.PropertyName = TestUtilsShared.GetRandomString();
        //    dmClass.Properties.CreateBusinessObject().PropertyName = TestUtilsShared.GetRandomString();
        //    wizardController.Solution = solution;
        //    wizardController.Class = dmClass;
        //    dmClass.UIViews.CreateBusinessObject();
        //    columnPropertiesWizardStep.PropertiesSelectorControl.Model.Select(dmProperty.PropertyName);
        //    //--------------- Test Preconditions ----------------
        //    Assert.IsNotNull(wizardController.Class);
        //    Assert.IsNotNull(columnPropertiesWizardStep.SelectedClass);
        //    Assert.AreEqual(1, columnPropertiesWizardStep.PropertiesSelectorControl.Model.SelectedOptions.Count);
        //    Assert.AreEqual(1, dmClass.UIViews.Count);
        //    //--------------- Execute Test ----------------------
        //    string message;
        //    try
        //    {
        //        wizardController.CanMoveOn(out message);
        //        Assert.Fail("Should have failed");
        //    }
        //        //--------------- Test Result -----------------------
        //    catch (UserException ex)
        //    {
        //        StringAssert.Contains("You cannot create a grid definition for the entity '" + dmClass.ToString()
        //                              + "' as it already has a UIView defined.", ex.Message);
        //    }
        //}

        [Test]
        public void Test_FilterStep2_ShouldOnlyShowSelectedOptionsFromStep1()
        {
            //--------------- Set up test pack ------------------
            CreateViewWizardController wizardController = new CreateViewWizardController();
            SelectPropertiesWizardStep propertyColumnsWizardStep =
                (SelectPropertiesWizardStep) wizardController.GetFirstStep();

            DMSolution solution = TestUtilsDMSolution.CreateSavedDMSolutionWithTwoClasses();
            DMClass dmClass = solution.AllClasses[1];
            TestUtilsDMProperty.CreateUnsavedValidDMProperty(dmClass);
            DMProperty selectedProp = TestUtilsDMProperty.CreateUnsavedValidDMProperty(dmClass, false);
            wizardController.Class = dmClass;
            IMultiSelector<string> propertiesSelectorControl = propertyColumnsWizardStep.PropertiesSelectorControl;
            propertiesSelectorControl.Model.Select(selectedProp.PropertyName);
            SelectPropertiesFilterWizardStep propertyColumnsWizardStep2 =
                (SelectPropertiesFilterWizardStep) wizardController.GetNextStep();
            wizardController.GetPreviousStep();
            IMultiSelector<string> propertiesSelectorControl2 = propertyColumnsWizardStep2.PropertiesSelectorControl;
            //---------------Assert Precondition----------------
            Assert.IsNotNull(wizardController.Class);
            Assert.IsNull(wizardController.UIGrid);
            IList<string> availableOptions = propertiesSelectorControl.Model.AvailableOptions;
            Assert.AreEqual(1, availableOptions.Count);
            IList<string> selectedOptions = propertiesSelectorControl.SelectedOptions;
            Assert.AreEqual(1, selectedOptions.Count);
            Assert.IsFalse(selectedProp.IsPartOfObjectIdentity);
            Assert.IsFalse(selectedProp.KeepValuePrivate.GetValueOrDefault());
            IList<string> availableFilterOptions = propertiesSelectorControl2.Model.AvailableOptions;
            Assert.AreEqual(2, availableFilterOptions.Count);

            //--------------- Execute Test ----------------------
            string message;
            bool canMoveOn = wizardController.CanMoveOn(out message);

            //--------------- Test Result -----------------------
            Assert.IsTrue(canMoveOn);
            Assert.AreEqual("", message);
            availableFilterOptions = propertiesSelectorControl2.Model.AvailableOptions;
            Assert.AreEqual(1, availableFilterOptions.Count);
            Assert.IsTrue(availableFilterOptions.Contains(selectedProp.PropertyName));
        }

        //[Test]
        //public void Test_SetClass_ShouldRaiseError_WhenSelectedClassAlreadyHasUIView()
        //{
        //    //--------------- Set up test pack ------------------
        //    CreateViewWizardController wizardController = new CreateViewWizardController();

        //    DMSolution solution = TestUtilsDMSolution.CreateSavedDMSolutionWithTwoClasses();
        //    DMClass dmClass = solution.AllClasses[1];
        //    dmClass.UIViews.CreateBusinessObject();
        //    TestUtilsDMProperty.CreateUnsavedValidDMProperty(dmClass);
        //    //--------------- Test Preconditions ----------------
        //    Assert.AreEqual(1, dmClass.UIViews.Count);
        //    //--------------- Execute Test ----------------------
        //    try
        //    {
        //        wizardController.Class = dmClass;
        //        Assert.Fail("expected Err");
        //    }
        //    //---------------Test Result -----------------------
        //    catch (UserException ex)
        //    {
        //        StringAssert.Contains("You cannot create a grid definition for the entity '" + dmClass.ToString()
        //            + "' as it already has a UIView defined.", ex.Message);
        //    }
        //}

        [Test]
        public void Test_SetClass_ShouldNotRaiseError_WhenClassIsNull()
        {
            //--------------- Set up test pack ------------------
            CreateViewWizardController wizardController = new CreateViewWizardController();

            DMSolution solution = TestUtilsDMSolution.CreateSavedDMSolutionWithTwoClasses();
            DMClass dmClass = solution.AllClasses[1];
            wizardController.Class = dmClass;
            //--------------- Test Preconditions ----------------
            Assert.IsNotNull(wizardController.Class);
            //--------------- Execute Test ----------------------
            wizardController.Class = null;

            //---------------Test Result -----------------------
            Assert.IsNull(wizardController.Class);
        }

        [Test]
        public void TestAcceptance_FixBug_DeleteDMClassAndPropThatHasUIViewCreated_ShouldNotGiveError()
        {
            //---------------Set up test pack-------------------
            //   BORegistry.DataAccessor = new DataAccessorDB();
            CreateViewWizardController wizardController = new CreateViewWizardController();
            SelectPropertiesWizardStep propertyColumnsWizardStep =
                (SelectPropertiesWizardStep) wizardController.GetFirstStep();

            DMSolution solution = TestUtilsDMSolution.CreateSavedDMSolutionWithTwoClasses();
            DMClass dmClass = solution.AllClasses[1];
            TestUtilsDMProperty.CreateUnsavedValidDMProperty(dmClass);
            DMProperty selectedProp = TestUtilsDMProperty.CreateUnsavedValidDMProperty(dmClass, false);
            wizardController.Class = dmClass;
            IMultiSelector<string> propertiesSelectorControl = propertyColumnsWizardStep.PropertiesSelectorControl;
            propertiesSelectorControl.Model.Select(selectedProp.PropertyName);
            selectedProp.ObjectIdentity = null;
            wizardController.GetNextStep();
            wizardController.GetNextStep();
            wizardController.Finish();
            dmClass.Save();
            //---------------Assert Precondition----------------
            UIGridInfo gridInfo = wizardController.UIGrid;
            Assert.IsNotNull(gridInfo);
            BusinessObjectCollection<UIGridColumnInfo> gridColumnInfos = gridInfo.UIColumns;
            Assert.AreEqual(1, gridColumnInfos.Count);
            UIGridColumnInfo gridColumnInfo = gridColumnInfos[0];
            Assert.AreEqual(selectedProp.PropertyName, gridColumnInfo.PropertyName);
            //---------------Execute Test ----------------------
            new DMClassDeleter(dmClass).Delete();;
            //---------------Test Result -----------------------
            Assert.IsTrue(dmClass.Status.IsDeleted);
            Assert.IsTrue(selectedProp.Status.IsDeleted);
            Assert.IsTrue(gridColumnInfo.Status.IsDeleted);
        }

        [Test]
        public void TestAcceptance_Finish_ShouldCreateView_WithUniqueName()
        {
            //---------------Set up test pack-------------------
            CreateViewWizardController wizardController = new CreateViewWizardController();
            IWizardControl wzrdControl = GlobalUIRegistry.ControlFactory.CreateWizardControl(wizardController);
            wzrdControl.Start();
            SelectPropertiesWizardStep gridPropSelector = (SelectPropertiesWizardStep)wizardController.GetFirstStep();

            DMSolution solution = TestUtilsDMSolution.CreateSavedDMSolutionWithTwoClasses();
            DMClass dmClass = solution.AllClasses[1];
            UIView uiView1 = dmClass.UIViews.CreateBusinessObject();
            TestUtilsDMProperty.CreateUnsavedValidDMProperty(dmClass);
            DMProperty selectedProp = TestUtilsDMProperty.CreateUnsavedValidDMProperty(dmClass);

            wizardController.Class = dmClass;
            IMultiSelector<string> propertiesMultiSelectorControl = gridPropSelector.PropertiesSelectorControl;
            propertiesMultiSelectorControl.Model.Select(selectedProp.PropertyName);
            selectedProp.ObjectIdentity = null;
            selectedProp.KeepValuePrivate = false;
            //---------------Assert Precondition----------------
            Assert.AreSame(dmClass, wizardController.Class);
            Assert.AreEqual(1, dmClass.UIViews.Count);
            Assert.AreEqual("default", dmClass.UIViews[0].ViewName);
            Assert.IsNull(wizardController.GridFilter);
            IList<string> availableOptions = propertiesMultiSelectorControl.Model.AvailableOptions;
            Assert.AreEqual(1, availableOptions.Count);
            IList<string> selectedOptions = propertiesMultiSelectorControl.SelectedOptions;
            Assert.AreEqual(1, selectedOptions.Count);
            Assert.IsFalse(selectedProp.IsPartOfObjectIdentity);
            Assert.IsFalse(selectedProp.KeepValuePrivate.Value);
            SelectPropertiesFilterWizardStep gridFilterPropSelector = wizardController.SelectFilterPropertiesWizardStep;
            Assert.AreEqual
                (dmClass.Properties.Count, gridFilterPropSelector.PropertiesSelectorControl.Model.AvailableOptions.Count,
                 "Should have all the Classes Properties available");
            Assert.IsTrue(wizardController.IsFirstStep());
            //---------------Execute First Step ----------------------
            wzrdControl.NextButton.PerformClick();
            //---------------Assert Results First Step ---------------
            Assert.IsFalse(wizardController.IsFirstStep());
            //Should Set the Available Options in the Grid Filter to the columns
            // selected in the Grid.
            Assert.AreEqual(1, gridFilterPropSelector.PropertiesSelectorControl.Model.AvailableOptions.Count);

            //--------------Select the Property ----------------------
            IMultiSelector<string> filterPropertiesMultiSelectorControl = gridFilterPropSelector.PropertiesSelectorControl;
            filterPropertiesMultiSelectorControl.SelectedOptionsListBox.ClearSelected();
            //--------------Assert Preconditions to Finish-------------
            IList<string> selectedFilterProps = filterPropertiesMultiSelectorControl.SelectedOptions;
            Assert.AreEqual(0, selectedFilterProps.Count);
            Assert.IsNull(wizardController.UIGrid);
            Assert.IsNull(wizardController.GridFilter);

            //--- Execute Second Step (Finish Wizard) ----------------
            wzrdControl.NextButton.PerformClick();
            wzrdControl.FinishButton.PerformClick();
            //----Assert Results Second Step--------------------------
            //Should Create Grid with selected property
            UIGridInfo grid = wizardController.UIGrid;
            Assert.IsNotNull(grid);
            Assert.AreEqual(1, grid.UIColumns.Count);
            //Should Not Create Grid Filter if no Selected Properties.
            Assert.IsNull(wizardController.GridFilter);
            Assert.IsNull(grid.UIGridFilter);

            //-----------------Verify That A UIView is created for the Class with
            //  The appropriate Grid and Form Infos
            Assert.AreEqual(2, dmClass.UIViews.Count);
            UIView uiView = dmClass.UIViews[1];
            Assert.AreEqual("default1", uiView.ViewName);
            Assert.IsNotNull(uiView.UIGridInfo);
            Assert.AreSame(grid, uiView.UIGridInfo);
            Assert.IsNotNull(uiView.UIFormInfo);
//            Assert.AreEqual(2, uiView.UIFormInfo.UIFields.Count);
        }

        [Test]
        public void Test_CreateForm_WhenNotHasPropsShouldNotCreateForm()
        {
            //---------------Set up test pack-------------------
            var wizardController = new CreateViewWizardControllerSpy();
            var dmClass = TestUtilsDMClass.GetFactory()
                .WithOutSingleRelationships()
                .CreateValidBusinessObject();

            IList<string> selectedFormProps = new List<string>();
            //---------------Assert Precondition----------------
            Assert.IsEmpty(dmClass.Properties);
            Assert.AreEqual(0, selectedFormProps.Count);
            //---------------Execute Test ----------------------
            var createdForm = wizardController.CallCreateForm(dmClass, selectedFormProps);
            //---------------Test Result -----------------------
            Assert.IsNull(createdForm);
        }
        [Test]
        public void Test_CreateForm_WhenHasProps_ShouldCreateForm()
        {
            //---------------Set up test pack-------------------

            var wizardController = new CreateViewWizardControllerSpy();
            var dmClass = TestUtilsDMClass.GetFactory()
                .WithMany(@class => @class.Properties)
                .WithOutSingleRelationships()
                .WithValue(class1 => class1.Assembly, GetDMSolution().DefaultAssembly)
                .CreateValidBusinessObject();

            IList<string> selectedFormProps = dmClass.Properties.Select(dmProperty => dmProperty.PropertyName).ToList();
            //---------------Assert Precondition----------------
            Assert.Greater(selectedFormProps.Count, 1);
            //---------------Execute Test ----------------------
            var createdForm = wizardController.CallCreateForm(dmClass, selectedFormProps);
            //---------------Test Result -----------------------
            Assert.IsNotNull(createdForm);
        }

        private DMSolution GetDMSolution()
        {
            var solutionCreator = new SolutionCreator();
            return solutionCreator.CreateSolution();
        }

        /// <summary>
        /// To get this to work you need to Modify the UIFormCreator.
        /// This code needs to be similar to UIGridCreator.CreateGrid and CreateColumn.
        /// </summary>
        [Test]
        public void Test_CreateForm_WhenSelectedSomeProps_ShouldCreateForm_WithOnlyThoseProps()
        {
            //---------------Set up test pack-------------------
            var wizardController = new CreateViewWizardControllerSpy();

            var dmClass = TestUtilsDMClass.GetFactory()
                .WithMany(@class => @class.Properties)
                .WithOutSingleRelationships()
                .WithValue(class1 => class1.Assembly, GetDMSolution().DefaultAssembly)
                .CreateValidBusinessObject();

            IList<string> selectedFormProps = new List<string>();
            var expectedPropName = dmClass.Properties[0].PropertyName;
            selectedFormProps.Add(expectedPropName);
            //---------------Assert Precondition----------------
            Assert.AreEqual(1, selectedFormProps.Count);
            //---------------Execute Test ----------------------
            var createdForm = wizardController.CallCreateForm(dmClass, selectedFormProps);
            //---------------Test Result -----------------------
            Assert.IsNotNull(createdForm);
            Assert.AreEqual(1, createdForm.UIFields.Count);
            Assert.AreEqual(expectedPropName, createdForm.UIFields[0].PropertyName);
        }


        [Test]
        public void Test_CreateUIView_WhenSelectedSomeProps_ShouldCreateUIViewWithUIForm_WithOnlyThoseProps()
        {
            //---------------Set up test pack-------------------
            var wizardController = new CreateViewWizardControllerSpy();

            var dmClass = TestUtilsDMClass.GetFactory()
                .WithMany(@class => @class.Properties)
                .WithOutSingleRelationships()
                .WithValue(class1 => class1.Assembly, GetDMSolution().DefaultAssembly)
                .CreateValidBusinessObject();

            var expectedPropName = dmClass.Properties[0].PropertyName;
            IList<string> selectedFormProps = new List<string> {expectedPropName};
            //---------------Assert Precondition----------------
            Assert.AreEqual(1, selectedFormProps.Count);
            //---------------Execute Test ----------------------
            var createdUIView = wizardController.CallCreateUIView(dmClass, selectedFormProps);
            //---------------Test Result -----------------------
            var uiForm = createdUIView.UIFormInfo;
            Assert.IsNotNull(uiForm);
            Assert.AreEqual(1, uiForm.UIFields.Count);
            Assert.AreEqual(expectedPropName, uiForm.UIFields[0].PropertyName);
        }


        [Test]
        public void Test_CreateGrid_WhenSelectedSomeProps_ShouldCreateCreateGrid_WithOnlyThoseProps()
        {
            //---------------Set up test pack-------------------
            var wizardController = new CreateViewWizardControllerSpy();

            var dmClass = TestUtilsDMClass.GetFactory()
                .WithMany(@class => @class.Properties)
                .WithOutSingleRelationships()
                .WithValue(class1 => class1.Assembly, GetDMSolution().DefaultAssembly)
                .CreateValidBusinessObject();

            var expectedPropName = dmClass.Properties[0].PropertyName;
            IList<string> selectedFormProps = new List<string> { expectedPropName };
            //---------------Assert Precondition----------------
            Assert.AreEqual(1, selectedFormProps.Count);
            //---------------Execute Test ----------------------
            var createdGrid = wizardController.CallCreateUIGrid(dmClass, selectedFormProps);
            //---------------Test Result -----------------------
            Assert.IsNotNull(createdGrid);
            Assert.AreEqual(1, createdGrid.UIColumns.Count);
            Assert.AreEqual(expectedPropName, createdGrid.UIColumns[0].PropertyName);
        }



        [Test]
        public void Test_CreateGrid_WhenNoSelectedSomeProps_ShouldNotCreateUIGrid()
        {
            //---------------Set up test pack-------------------
            var wizardController = new CreateViewWizardControllerSpy();

            var dmClass = TestUtilsDMClass.GetFactory()
                .WithMany(@class => @class.Properties)
                .WithOutSingleRelationships()
                .WithValue(class1 => class1.Assembly, GetDMSolution().DefaultAssembly)
                .CreateValidBusinessObject();
            IList<string> selectedFormProps = new List<string>();
            //---------------Assert Precondition----------------
            Assert.AreEqual(0, selectedFormProps.Count);
            //---------------Execute Test ----------------------
            var createdGrid = wizardController.CallCreateUIGrid(dmClass, selectedFormProps);
            //---------------Test Result -----------------------
            Assert.IsNull(createdGrid);
        }
        #region Create UIForm

        private class CreateViewWizardControllerSpy : CreateViewWizardController
        {
            public UIFormInfo CallCreateForm(DMClass dmClass, IList<string> selectedFormProps)
            {
                return CreateForm(dmClass, selectedFormProps);
            }
            public UIView  CallCreateUIView(DMClass dmClass, IList<string> selectedFormProps)
            {
                return CreateUIView(dmClass, new List<string>(), new List<string>() , selectedFormProps);
            }

            public UIGridInfo CallCreateUIGrid(DMClass dmClass, IList<string> selectedProps)
            {
                CreateGrid(dmClass, selectedProps);
                return this.UIGrid;
            }
        }
        #endregion

    }
}